package zisu.netty.practice.netty.my;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * @Desc: ""
 * @Author: caixiang
 * @DATE: 2022/1/12 14:50
 */
public enum NettyClient {
    INSTANCE("127.0.0.1",6668);
    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);
    private NioEventLoopGroup eventExecutors;
    private Bootstrap bootstrap;
    private ChannelFuture connection;
    private String ipAddress;
    private Integer port;
    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    NettyClient(String ipAddress,Integer port){
        this.ipAddress = ipAddress;
        this.port = port;
        connect(ipAddress,port);
    }

    public void connect(String host,int port ){
        //重新初始化 对象
        this.eventExecutors = new NioEventLoopGroup();
        this.bootstrap = new Bootstrap();
        ////设置线程组
        this.bootstrap.group(this.eventExecutors)
                //设置客户端通道的实现类（反射来处理）
                .channel(NioSocketChannel.class)
                .handler(new MyClientInitializer());

        try {
            this.connection = this.bootstrap.connect(ipAddress, port).sync();
            ////等待服务端监听端口关闭, 否者 这个线程会再这里阻塞住
            this.connection.channel().closeFuture().sync();

        }catch (Exception e){
            e.printStackTrace();
            eventExecutors.shutdownGracefully();
        }finally {
            //断线 重连，，等资源回收以后再发起重连
            System.out.println();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        TimeUnit.SECONDS.sleep(5);
                        //重新发起重连操作
                        connect(host,port);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }
    }


    public ChannelFuture getConnection(){
        return this.connection;
    }


}
